package com.crazyhat.crazyhat.controller;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.crazyhat.crazyhat.anno.AdminOnly;
import com.crazyhat.crazyhat.attribute.TokenPayloadEnum;
import com.crazyhat.crazyhat.attribute.UserTypeEnum;
import com.crazyhat.crazyhat.dto.UserInfoDTO;
import com.crazyhat.crazyhat.entity.Application;
import com.crazyhat.crazyhat.entity.User;
import com.crazyhat.crazyhat.pojo.EmailRequest;
import com.crazyhat.crazyhat.pojo.LoginRequest;
import com.crazyhat.crazyhat.pojo.PersonalCenter;
import com.crazyhat.crazyhat.pojo.Result;
import com.crazyhat.crazyhat.pojo.UserRegistrationRequest;
import com.crazyhat.crazyhat.service.IEmailService;
import com.crazyhat.crazyhat.service.IUserService;
import com.crazyhat.crazyhat.service.IVerificationCodeService;
import com.crazyhat.crazyhat.utils.JwtUtil;
import com.crazyhat.crazyhat.utils.Md5Util;
import com.crazyhat.crazyhat.utils.ScanImage;
import com.crazyhat.crazyhat.utils.ThreadLocalUtil;

import jakarta.servlet.http.HttpServletRequest;



/**
 * <p>
 * 用户 前端控制器
 * </p>
 *
 * 用户控制器，用于处理用户相关的请求，如发送验证码、获取用户信息、注册和登录。
 *
 * @author crazyhat
 * @since 2024-07-05
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private IUserService userService; // 用户服务，用于处理用户信息

    @Autowired
    private IEmailService emailService; // 邮件服务，用于发送邮件

    @Autowired
    private IVerificationCodeService verificationCodeService; // 验证码服务，用于处理验证码

    /**
     * 发送验证码到指定的邮箱，有效期：5 minute，重发间隔：1 minute
     *
     * @param email 接收验证码的邮箱地址
     * @return 操作结果
     */
    @PostMapping("/sendCode")
    public Result sendVerificationCode(@RequestBody @Validated EmailRequest emailRequest) {
        String email = emailRequest.getEmail();
        if (!verificationCodeService.canSendCode(email)) {
            return Result.error("您每分钟只能请求一次验证码");
        }
        String code = String.valueOf((int) (Math.random() * 9000) + 1000);
        verificationCodeService.saveCode(email, code);
        emailService.sendVerificationCode(email, code);

        return Result.success();
    }


    /**
     * 根据学号获取用户信息
     *
     * @param studentId 用户的学号
     * @return 用户信息
     */
    @GetMapping("/userinfo")
    public Result getUserInfo(@RequestParam("studentId") String studentId) {
        // 根据学号获取用户信息
        User user = userService.getUserInfoByStudentId(studentId);
        return Result.success(user);
    }

    @GetMapping("/myInfo")
    public Result getMyInfo() {

        // 根据学号获取用户信息
        User user = userService.getMyInfo();

        if (user!=null) {
            return Result.success(user);
        } else {
            return Result.error("获取用户信息失败");
        }

    }


    /**
     * 用户注册
     *
     * @param userRequest 用户注册请求，包括邮箱、密码、学号、姓名和验证码
     * @return 注册结果
     */
    @PostMapping("/register")
    public Result registerUser(@RequestBody @Validated UserRegistrationRequest userRequest) {

        String storedCode = verificationCodeService.getCode(userRequest.getEmail());
        if (storedCode == null || !storedCode.equals(userRequest.getVerificationCode())) {
            return Result.error("验证码无效");
        }

        User user = new User();
        user.setEmail(userRequest.getEmail());
        user.setPassword(userRequest.getPassword());
        user.setStudentId(Integer.valueOf(userRequest.getStudentId()));
        user.setName(userRequest.getName());
        user.setUserType(UserTypeEnum.OrdinaryUser);

        return Result.success(userService.registerUser(user));
    }


    /**
     * 用户登录
     *
     * @param loginRequest 登录请求，包括邮箱和密码
     * @return 登录结果，包括生成的JWT令牌
     */
    @PostMapping("/login")
    public Result loginUser(@RequestBody @Validated LoginRequest loginRequest) {
        User user = userService.authenticateUser(loginRequest.getIdentifier(), loginRequest.getPassword());
        if (user != null) {
            System.out.println("用户登录成功： " + user.getEmail());

            String token = JwtUtil.generateToken(Map.of(
                    TokenPayloadEnum.Email.getValue(), user.getEmail(),
                    TokenPayloadEnum.StudentId.getValue(), user.getStudentId(),
                    TokenPayloadEnum.Name.getValue(), user.getName(),
                    TokenPayloadEnum.UserType.getValue(), user.getUserType().getValue()
            ));
            return Result.success(token);
        } else {
            System.out.println("账号或密码错误：" + loginRequest.getIdentifier());
            return Result.error("账号或密码错误");
        }
    }

    /**
     * 用户重置密码接口
     * @param request 请求参数，包括邮箱、验证码和新密码
     * @return 重置密码结果
     */
    @PostMapping("/resetPassword")
    public Result resetPassword(@RequestBody Map<String, String> request) {
        String email = request.get("email");
        String code = request.get("code");
        String newPassword = request.get("newPassword");
        if (!verificationCodeService.isCodeValid(email, code)) {
            return Result.error("验证码无效");
        }

        // 校验密码格式
        if (!isValidPassword(newPassword)) {
            return Result.error("密码长度必须在6到20个字符之间，并且只能包含字母、数字和@._符号");
        }

        User user = userService.getUserByEmail(email);
        if (user == null) {
            return Result.error("未找到用户");
        }

        user.setPassword(Md5Util.getMD5String(newPassword)); // Encrypt the new password before saving
        userService.updateUser(user);
        return Result.success("密码重置成功");
    }

    private boolean isValidPassword(String password) {
        String passwordPattern = "^[a-zA-Z0-9@._]{6,20}$";
        return password != null && password.matches(passwordPattern);
    }

    /**
     * 获取当前用户个人中心的信息
     * @param
     * @return
     */
    @GetMapping("/personalCenter")
    public Result personalCenter(int footprintPageNum){
        PersonalCenter personalCenter=userService.getPersonalCenter(footprintPageNum);
        return Result.success(personalCenter);
    }

    /**
     * 更新用户信息
     * @param user
     * @return
     */
    @PutMapping("/updateUserInfo")
    public Result updateUserInfo(@RequestBody @Validated User user) {

        User user1=userService.updateUserInfo(user);
        if(user1==null){
            return Result.error("修改失败");
        }
        return Result.success(user1);
    }


    //用户管理 返回用户信息
    @AdminOnly
    @GetMapping("/all")
    public Result<List<UserInfoDTO>> getAllUsers() {
        List<UserInfoDTO> users = userService.getAllUsers();
        return Result.success(users);
    }

    //用户管理 批量删除
    @AdminOnly
    @DeleteMapping("/delete")
    public Result deleteUsers(@RequestBody List<Integer> studentIds) {
        boolean success = userService.deleteUsers(studentIds);
        if (success) {
            return Result.success("用户删除成功");
        } else {
            return Result.error("删除失败，无法删除系统管理员或无效的学生ID");
        }
    }

    /**
     * 用户管理
     * 重置用户密码为学号后六位
     *
     * @param studentId 用户学号
     * @return 重置结果
     */
    @AdminOnly
    @PostMapping("/resetPassword/{studentId}")
    public Result resetPassword(@PathVariable Integer studentId) {
        boolean success = userService.resetPassword(studentId);
        if (success) {
            return Result.success("密码重置成功");
        } else {
            return Result.error("重置密码失败");
        }
    }

    /*
    * 用户换头像
    * */
    @PutMapping("/changeAvatar")
    public Result changeAvatar(MultipartFile avatar){
        boolean strict =true;
        if (avatar == null|| avatar.isEmpty()) {
            return Result.error("上传的图片为空");
        }

        if (ScanImage.scanAndApprove(avatar,strict)) {
            String result=userService.changeAvatar(avatar);

            if(result==null){
                return Result.error("更换头像失败");
            }

            return Result.success(result);
        } else {
            return Result.error("上传的图片违规");
        }
    }
    /**
     * 查看我的所有申请
     */
    @GetMapping("/personalApplications")
    public Result<Page<Application>> personalApplications(int pageNum,int pageSize){
        Page<Application> applicationPage=userService.personalApplications(pageNum,pageSize);
        return Result.success(applicationPage);
    }

    /**
     * 注销用户
     * @return 注销结果
     */
    @DeleteMapping("/logout")
    public Result logoutUser(HttpServletRequest request) {  // 添加 HttpServletRequest 参数
        Map<String, Object> userInfo = ThreadLocalUtil.get();
        if (userInfo == null) {
            return Result.error("用户未登录");
        }

        Integer studentId = (Integer) userInfo.get("studentId");
        String email = (String) userInfo.get("email");
        String token = request.getHeader("Authorization");

        if (userService.logoutUser(studentId, email, token)) {
            return Result.success("注销成功");
        } else {
            return Result.error("注销失败");
        }
    }
    /*
     * 查看我的待审核申请
     */
    @GetMapping("/pendingApplications")
    public Result<Page<Application>> pendingApplications(int pageNum,int pageSize){
        Page<Application> applicationPage=userService.pendingApplications(pageNum,pageSize);
        return Result.success(applicationPage);
    }

    /*
     * 查看用户类型
     */
    @GetMapping("/getUserType")
    public Result getUserType(){
        String type=userService.getUserType();
        return Result.success(type);
    }

    /*
    * 管理员修改用户信息
    * */
    @PostMapping("/adminModifyUserInfo")
    public Result adminModifyUserInfo(MultipartFile avatar,String name,String studentId){
        boolean strict =true;
        User user;
        if(avatar!=null){
            if (ScanImage.scanAndApprove(avatar,strict)) {
                user=userService.adminModifyUserInfo(avatar,name,studentId);
                if(user==null){
                    return Result.error("更改信息失败");
                }
                return Result.success(user);
            } else {
                return Result.error("图片违规");
            }
        }
        user=userService.adminModifyUserInfo(avatar,name,studentId);
        if(user==null){
            return Result.error("更改信息失败");
        }
        return Result.success(user);
    }
}
